package jfae.core.configuration;

import java.util.Set;

import jfae.core.configuration.contributions.BaseContribution;
import jfae.core.properties.FieldInfo;
import jfae.core.properties.parsers.PropertyHandler;
import jfae.core.properties.parsers.annotation.AnnotationHandler;
import jfae.core.utils.InitializerWrapper;

public class JFaeLoader {
	
	public void initFramework(){
		Class<?>[] initilizers = getApplicationsInitializers();
		InitializerWrapper[] wrappers = new InitializerWrapper[initilizers.length];
		for (int i=0,j=initilizers.length; i<j; i++) {
			wrappers[i] = new InitializerWrapper(initilizers[i]);
		}
		initAnnotationsHandlers(wrappers);
		initPropertiesHandlers(wrappers);
	}

	private void initPropertiesHandlers(InitializerWrapper[] wrappers) {
		BaseContribution<PropertyHandler<FieldInfo<?>>> contributions = new BaseContribution<PropertyHandler<FieldInfo<?>>>();
		for (InitializerWrapper wrapper : wrappers) {
			wrapper.contributePropertiesHandlers(contributions);
		}
		for (InitializerWrapper wrapper : wrappers) {
			wrapper.overridePropertiesHandlers(contributions);
		}
		Set<String> ids = contributions.keySet();
		for (String id : ids) {
			JFaeConfiguration.add(id, contributions.get(id));
		}
	}

	private void initAnnotationsHandlers(InitializerWrapper[] wrappers) {
		BaseContribution<AnnotationHandler<?>> contributions = new BaseContribution<AnnotationHandler<?>>();
		for (InitializerWrapper wrapper : wrappers) {
			wrapper.contributeAnnotationsHandlers(contributions);
		}
		for (InitializerWrapper wrapper : wrappers) {
			wrapper.overrideAnnotationsHandlers(contributions);
		}
		Set<String> ids = contributions.keySet();
		for (String id : ids) {
			JFaeConfiguration.add(id, contributions.get(id));
		}
	}

	protected Class<?>[] getApplicationsInitializers() {
		// FIXME: imlementazione di prova
		return new Class<?>[]{CoreInitializer.class};
		/*
		 * TODO: angelo
		 * implementare logica di caricamento delle calssi
		 * dai progetti coinvolti.
		 * Il sistema poterebbe basarsi sulla presenza in una dir o jar
		 * di un file <proj-name>.jfae es: core.jfae
		 * Questo implicherebbe l'esistenza di una classe CoreInitializer.class
		 * in <proj-name>.jfae potrebbero esserci informazioni se tornerà utile
		 * 
		 * In alternativa si potrebbe creare un'annotation JFaeInitializer e cercare 
		 * sempplicemente le classi così configurate
		 * 
		 * dammi anche un tuo parere, tieni conto che devi accertarti del
		 * corretto funzionamento della ClassSearchUtils per decidere 
		 * l'approccio
		 */
	}
	
}
